# -*- coding: utf-8 -*-
"""
Created on Tue Apr 11 21:10:10 2017

@author: BaiYunfei
"""
import bs4
import re
import pandas as pd
from extrator.TPR.nodePath import NodePath


class TPR:
    
    def __init__(self, soup=None, html=None):
        if soup is not None:
            node = soup
        else:
            node = bs4.BeautifulSoup(html, 'lxml')
        self.dom = node
        self.pathDic = {}
        self.txtNumStd = 0
        self.puncNumStd = 0
        self.__count_path_num(node)
        self.data = self.__cal_tpr()
        
    def __count_path_num(self, node, p=None):
        if isinstance(node, bs4.element.Comment):
            return ;
        if p is None:
            p = [node.name]
        
        if TPR.is_text_node(node):
            if TPR.clean(node).strip() is '':
                return ;
            path_tag = str(p)
            path = self.pathDic.get(path_tag)
            if path is None:
                path = NodePath(path_tag)
                path.append(TPR.clean(node))
                path.textNum = len(TPR.clean(node).strip())
                path.pathNum = 1
                path.puncNum = TPR.count_punctuations(node)
                
                self.pathDic[path_tag] = path
            else:
                path.textNum = path.textNum + len(TPR.clean(node).strip())
                path.pathNum = path.pathNum + 1
                path.puncNum = path.puncNum + TPR.count_punctuations(node)
                path.nodes.append(TPR.clean(node))
        elif isinstance(node, bs4.element.Tag):
            p.append(node.name + str(node.attrs.get('class')))
            for n in node.children:
                self.__count_path_num(n, p.copy())

    def __cal_tpr(self):
        data = pd.DataFrame(self.pathDic, index=['node']).T
        data['path'] = data.index
        data.index = range(len(self.pathDic))

        data['textNum'] = [n.textNum for n in data.node]
        data['pathNum'] = [n.pathNum for n in data.node]
        data['puncNum'] = [n.puncNum for n in data.node]
        data['puncNum'] = data.puncNum.replace(0,1)
        for i in data.index:
            tag = data.loc[i].path[0:-1]
            for j in data.index:
                if i == j :
                    continue
                #匹配到可以合并的节点
                try:
                    if data.loc[j].path.index(tag) >= 0:
                        data.loc[i, 'textNum'] += data.loc[j].textNum
                        data.loc[i, 'pathNum'] += data.loc[j].pathNum
                        data.loc[i, 'puncNum'] += data.loc[j].puncNum
                        for n in data.loc[j].node.nodes:
                            data.loc[i, 'node'].append(n)
                        data = data.drop(j)
                        break
                except:
                    continue

        self.puncNumStd = data.puncNum.std()
        self.txtNumStd = data.textNum.std()

        data['tpr'] = ( data.textNum / data.pathNum ) * (data.puncNum) * self.puncNumStd * self.txtNumStd

        return data

    @staticmethod
    def clean(node):
        if isinstance(node, bs4.element.Tag):
            html = node.text
        else:
            html= node
        # 去除标签
        regex = re.compile(r'(?is)<.*?>')
        text = regex.sub('', html)
        # text = re.compile(r'\s').sub('', text)
        return text
        # return node
        
    @staticmethod
    def is_text_node(node):
        if isinstance(node, bs4.element.NavigableString):
            return True
        name_list = ['p', 'font', 'a', 'em', 'span', 'i', 'strong']
        if isinstance(node, bs4.element.Tag) & (node.name in name_list):
            return True
        for n in node.children:
            if isinstance(n, bs4.element.Tag):
                return False
        return True
#         return False

    @staticmethod
    def count_punctuations(target):
        reg = re.compile(r"《|》|——|；|，|。|“|”|！|、")
        return len(reg.findall(str(target)))
